﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Styx.CommonBot;
using Styx;
using Styx.WoWInternals.WoWObjects;
using System.IO;
using System.Windows.Forms;
using System.Media;
using Styx.WoWInternals;

namespace ShutUp
{
    class ChatHelper
    {
        private static readonly ShutUp _ShutUp = new ShutUp();
        private static StreamWriter writer;
        private static LocalPlayer Me { get { return StyxWoW.Me; } }
        private static string lastMessage = string.Empty;
        private static Random random = new Random();
        private static int lastRndMsg = 0;

        public static string soundLoopStatus = string.Empty;
        public static int loop = 0;
        public static Timer _timer;


        #region newChat_Whisper

        public static void newChat_Whisper(Chat.ChatWhisperEventArgs args)
        {
            if (args.Author == Me.Name || args.Message == lastMessage)
                return;

            lastMessage = args.Message;
            _ShutUp.slog("you got a whisper from: {0} - {1}", args.Author, args.Message);


            #region isFriend
            if (FriendsList.isFriend(args.Author))
            {
                _ShutUp.slog("{0} is a Friend or GuildMember!", args.Author);

                if (ShutUpSettings.Instance.softIgnoFriend)                
                    if (IgnoreManager.onListOrAdd(args.Author))                    
                        if (IgnoreManager.Igno(args.Author, ShutUpSettings.Instance.softIgnoFrAfter))
                        {
                            _ShutUp.slog("(soft) ignore: {0}", args.Author);
                            if (ShutUpSettings.Instance.saveLog)
                                writeToLogFile(args.Author, "(soft igno) - " + args.Message);
                            return;
                        }

                if (ShutUpSettings.Instance.SoundByFriend)
                    PlaySound("friend");

                if (ShutUpSettings.Instance.saveLog)
                    writeToLogFile(args.Author, args.Message);

                if (ShutUpSettings.Instance.answerWisper_Friends)
                    answerPlayer(args.Author, args.Message, "whisper", null);

                return;
            }
            #endregion

            if(ShutUpSettings.Instance.ignoAll)
            {
                if (ShutUpSettings.Instance.ingameIgno)
                {
                    Lua.DoString("RunMacroText(\"/ignore " + args.Author + "\")");
                    _ShutUp.slog("(ingame)Ignore Player: {0}!", args.Author);
                    writeToLogFile(args.Author, "(inGameIgno) - " + args.Message);
                    return;
                }

                _ShutUp.slog("(soft) ignore: {0}", args.Author);
                if (ShutUpSettings.Instance.saveLog)
                    writeToLogFile(args.Author, "(soft igno) - " + args.Message);
                return;
            }

            if (ShutUpSettings.Instance.ignoXW)
                if (IgnoreManager.onListOrAdd(args.Author))
                    if (IgnoreManager.Igno(args.Author, ShutUpSettings.Instance.softIgnoAfter))
                    {
                        _ShutUp.slog("(soft) ignore: {0}", args.Author);
                        if (ShutUpSettings.Instance.saveLog)
                            writeToLogFile(args.Author, "(soft igno) - " + args.Message);
                        return;
                    }

            if (ShutUpSettings.Instance.SoundByUnknown)
                PlaySound("unknown");

            if (ShutUpSettings.Instance.saveLog)
                writeToLogFile(args.Author, args.Message);

            if (ShutUpSettings.Instance.answerWisper_unknown)
                answerPlayer(args.Author, args.Message, "whisper", null);
        }
        #endregion

        #region newChat_BNWhisper
        // CHAT_MSG_BN_WHISPER    
        // arg1    chat message 
        // arg2    author 
        // arg6    AFK/DND/GM "CHAT_FLAG_"..arg6 flags 
        // arg11    Chat lineID 
        // arg13    Bnet presenceID 
        public static void newChat_BNWhisper(object sender, LuaEventArgs args)
        {
            object[] Args = args.Args;
            string Message = Args[0].ToString();
            string PresenceId = Args[12].ToString();
            string Author = Lua.GetReturnValues(String.Format("return BNGetFriendInfoByID({0})", PresenceId))[2];

            if (Message == lastMessage)
                return;
            lastMessage = Message;

            _ShutUp.slog("you got a whisper from: {0} - {1}", Author, Message);
            _ShutUp.slog("{0} is a Bnet Friend!", Author);

            if (ShutUpSettings.Instance.softIgnoFriend)
                if (IgnoreManager.onListOrAdd(Author))
                    if (IgnoreManager.Igno(Author, ShutUpSettings.Instance.softIgnoFrAfter))
                    {
                        _ShutUp.slog("(soft) ignore: {0}", Author);
                        if (ShutUpSettings.Instance.saveLog)
                            writeToLogFile(Author, "(soft igno) - " + Message);
                        return;
                    }

            if (ShutUpSettings.Instance.SoundByFriend)
                PlaySound("friend");

            if (ShutUpSettings.Instance.saveLog)
                writeToLogFile(Author, Message);

            if (ShutUpSettings.Instance.answerWisper_Friends)
                answerPlayer(Author, Message, "bnet", PresenceId);
        }

        #endregion

        #region PlaySound
        public static void PlaySound(string status)
        {
            string selectedItem = string.Empty;
            bool _externalPlayer = false;

            switch (status)
            {
                case "friend":
                    selectedItem = ShutUpSettings.Instance.selectedSoundFriends;
                    _externalPlayer = ShutUpSettings.Instance.useExternalPlayer_Friends;
                    break;
                case "myName":
                    selectedItem = ShutUpSettings.Instance.selectedSoundMyName;
                    _externalPlayer = ShutUpSettings.Instance.useExternalPlayer_myName;
                    break;
                case "unknown":
                    selectedItem = ShutUpSettings.Instance.selectedSoundFriends;
                    _externalPlayer = ShutUpSettings.Instance.useExternalPlayer_unknown;
                    break;
                default:
                    return;
            }

            if (selectedItem == "bing sound")
            {
                System.Media.SystemSounds.Beep.Play();
                System.Media.SystemSounds.Beep.Play();
            }

            else if (File.Exists(Application.StartupPath + "\\Plugins\\ShutUp\\Sounds\\" + selectedItem))            
                selectedItem = Application.StartupPath + "\\Plugins\\ShutUp\\Sounds\\" + selectedItem;            
            else
            {
                foreach (string file in ShutUpGlobalSettings.Instance.soundFiles)
                {
                    if (file.Contains(selectedItem))
                    { selectedItem = file; break; }
                }
            }

            if (_externalPlayer)
                System.Diagnostics.Process.Start(selectedItem);
            else
                new SoundPlayer(selectedItem).Play();

            if (ShutUpSettings.Instance.SoundLoop == 0 || _ShutUp.loopTimer.IsRunning)
                return;

            soundLoopStatus = status;
            loop = 0;
            _ShutUp.loopTimer.Reset();
            _ShutUp.loopTimer.Start();

            //_timer.Stop();
            //_timer = new Timer();
            //_timer.Interval = (ShutUpSettings.Instance.SoundLoopEvery * 1000);
            //_timer.Tick += new EventHandler(_timer_Tick);
            //_timer.Start();
            //_ShutUp.dlog("start soundloop", "interval: {0}", (ShutUpSettings.Instance.SoundLoopEvery * 1000));
        }

        #endregion

        #region writeToLogFile
        private static void writeToLogFile(string Name, string Msg)
        {
            try
            {
                string _txt = string.Format("{0} ({1}) - {2} - {3} : {4}", DateTime.Now.ToShortDateString(), 
                    DateTime.Now.ToShortTimeString(), FriendsList.Status(Name), Name, Msg);
                writer = new StreamWriter(_ShutUp.ShutUpLogLocation, true);
                writer.WriteLine(_txt);
            }
            catch (Exception ex)
            { _ShutUp.dlog("write to LogFile \n\n{0}", ex); }

            writer.Close();
        }

        private static void writeToLogFile(string Name, string Msg, string Status)
        {
            try
            {
                string _txt = string.Format("{0} ({1}) - {2} - {3} : {4}", DateTime.Now.ToShortDateString(),
                    DateTime.Now.ToShortTimeString(), Status, Name, Msg);
                writer = new StreamWriter(_ShutUp.ShutUpLogLocation, true);
                writer.WriteLine(_txt);
            }
            catch (Exception ex)
            { _ShutUp.dlog("write to LogFile \n\n{0}", ex); }

            writer.Close();
        }
        #endregion

        #region myName

        public static void newChat_Party(Chat.ChatLanguageSpecificEventArgs args)
        {
            myName_Check("party", args.Author, args.Message);
        }
        
        public static void newChat_Say(Chat.ChatLanguageSpecificEventArgs args)
        {
            myName_Check("say", args.Author, args.Message);
        }

        public static void newChat_Guild(Chat.ChatGuildEventArgs args)
        {
            myName_Check("guild", args.Author, args.Message);
        }

        public static void newChat_Yell(Chat.ChatLanguageSpecificEventArgs args)
        {
            myName_Check("yell", args.Author, args.Message);
        }

        public static void newChat_Battleground(Chat.ChatLanguageSpecificEventArgs args)
        {
            myName_Check("BG", args.Author, args.Message);
        }

        public static void myName_Check(string Status, string Author, string Message)
        {
            if (Author == Me.Name)
                return;

            bool found = false;
            string _name = string.Empty;

            if (Message.Contains(Me.Name))
            { found = true; _name = Me.Name; }

            if (!found)
                foreach (string name in ShutUpGlobalSettings.Instance.myName_list)
                {
                    if (Message.Contains(name))
                    { found = true; _name = name; break; }
                }

            if (!found)
                foreach (string name in ShutUpSettings.Instance.myName_list)
                {
                    if (Message.Contains(name))
                    { found = true; _name = name; break; }
                }

            if (!found)
                return;

            _ShutUp.slog("({1}) - {0} says your name({2})!", Author, Status, _name);

            if (ShutUpSettings.Instance.SoundByMyName)
                PlaySound("myName");

            if (ShutUpSettings.Instance.saveLog)
                writeToLogFile(Author, string.Format("myName({0} - {1}) - {2}", Status, _name, Message));

            if (ShutUpSettings.Instance.myName_answer)
                answerPlayer(Author, Message, Status, null);

            if (ShutUpGlobalSettings.Instance.myName_showPopUp)
            { 
                var _popUpForm = new myNamePopUpForm();
                _popUpForm.Show();
            }
        }
        #endregion

        #region answer

        public static void answerPlayer(string Author, string Message, string Status, string BnetID)
        {
            try
            {

                int answerAfter = random.Next(ShutUpSettings.Instance.answerBetweenMin, ShutUpSettings.Instance.answerBetweenMax);
                int Rnd = random.Next(1, ShutUpGlobalSettings.Instance.randomAnswer.Length);
                while (Rnd == lastRndMsg)
                    Rnd = random.Next(1, ShutUpGlobalSettings.Instance.randomAnswer.Length);
                lastRndMsg = Rnd;
                string message = ShutUpGlobalSettings.Instance.randomAnswer[(Rnd - 1)].ToString();

                _ShutUp.slog("({0})answer [{1}] (in {2}sec) with: {3}", Status, Author, answerAfter, message);

                TreeRoot.StatusText = "[ShutUp]: \"write message\" wait " + answerAfter + "sec .. )";
                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(answerAfter));

                switch (Status)
                {
                    case "whisper":
                        Lua.DoString(string.Format("SendChatMessage(\"{0}\", 'WHISPER', nil, '{1}')", message, Author));
                        break;
                    case "say":
                        Lua.DoString(string.Format("SendChatMessage(\"{0}\", 'SAY')", message));
                        break;
                    case "yell":
                        Lua.DoString(string.Format("SendChatMessage(\"{0}\", 'YELL')", message));
                        break;
                    case "party":
                        Lua.DoString(string.Format("SendChatMessage(\"{0}\", 'PARTY')", message));
                        break;
                    case "guild":
                        Lua.DoString(string.Format("SendChatMessage(\"{0}\", 'GUILD')", message));
                        break;
                    case "raid":
                        Lua.DoString(string.Format("SendChatMessage(\"{0}\", 'RAID')", message));
                        break;
                    case "BG":
                        Lua.DoString(string.Format("SendChatMessage(\"{0}\", 'BATTLEGROUND')", message));
                        break;
                    case "bnet":
                        Lua.DoString(string.Format("BNSendWhisper('{0}', \"{1}\")", BnetID, message));
                        break;
                    default:
                        _ShutUp.slog(System.Windows.Media.Colors.Red, "Error in answerPlayer ..");
                        return;
                }
                TreeRoot.StatusText = "[ShutUp]: message sent..";
                _ShutUp.slog("message sent..");

                if (ShutUpSettings.Instance.saveLog)
                    writeToLogFile(Author, message, string.Format("ANSWER ({0})", Status));
            }
            catch (Exception ex)
            { _ShutUp.dlog("answerPlayer() \n\n{0}", ex); }
        }

        #endregion

        #region sound loop Ticker
        //public static void _timer_Tick(object sender, EventArgs e)
        //{
        //    _ShutUp.dlog("soundloop tick", "tick: {0}", loop);
        //    if (soundLoopFile == "bing sound")
        //    {
        //        System.Media.SystemSounds.Beep.Play();
        //        System.Media.SystemSounds.Beep.Play();
        //    }
        //    else if (soundLoopExternal)
        //        System.Diagnostics.Process.Start(soundLoopFile);
        //    else
        //        new SoundPlayer(soundLoopFile).Play();

        //    if (loop == ShutUpSettings.Instance.SoundLoop)
        //    { _ShutUp.dlog("stop soundloop", "tick: {0}", loop); _timer.Stop(); }

        //    loop++;
        //}
        #endregion

        #region convertToIcon
        /// <summary>
        /// convert a Image to Icon
        /// </summary>
        /// <param name="image">Image file</param>
        /// <param name="color">Make Transparent</param>
        /// <returns>the Image as Icon</returns>
        public static System.Drawing.Icon convertToIcon(System.Drawing.Image image, System.Drawing.Color color)
        {
            System.Drawing.Bitmap _bitmap = (System.Drawing.Bitmap)image;
            if (color != System.Drawing.Color.Empty)
                _bitmap.MakeTransparent(color);
            System.IntPtr _intPtr = _bitmap.GetHicon();
            System.Drawing.Icon _icon = System.Drawing.Icon.FromHandle(_intPtr);
            return _icon;
        }
        #endregion
    }






    public static class IgnoreManager
    {
        static public Dictionary<string, int> players = new Dictionary<string, int>();
        public static bool onListOrAdd(string name)
        {
            foreach (KeyValuePair<string, int> player in players)
            {
                if (player.Key == name)
                {
                    int i = player.Value; ++i;
                    players.Remove(name);
                    players.Add(name, i);
                    return true;
                }
            }
            players.Add(name, 1);
            return false;
        }

        public static bool Igno(string name, int max)
        {
            foreach (KeyValuePair<string, int> player in players)
            {
                if (player.Key == name && player.Value > max)
                {
                    return true;
                }
            }
            return false;
        }
    }
}
